import axios from 'axios';
import qs from 'qs';
import utils from '@/static/js/utils.js'
import config from '@/static/config.js';
import { signOut } from '@/static/js/sign.js';
import { Message } from 'element-ui';


// 错误处理
const errorHandle = (status, message, request) => {
    let msg = message || '系统错误，请联系管理员！'
    switch (status) {
        case 400:   
        case 403:   // 未授权 token过期 访问失败，用户缺少访问权限：用户管理:查询在线人员
        case 500:
        case 504:
            Message({
                message: msg,
                type: 'error',
                duration: 3 * 1000
            })
        break;
        case 401:
            // 401: 未登录状态，跳转登录页
            // 未认证(用户未登陆)
            // 退出接口返回401，需要过滤掉
            // 回到登录页
            signOut();
        break;
        case 404:
            console.log(404);
        break;
        default:
            Message({
                message: msg,
                type: 'error',
                duration: 3 * 1000
            })
        break;
    }
};

// 创建axios实例
let instance =  axios.create({
    baseURL: config.baseUrl,    // api的base_url
    timeout: config.timeout     // 请求超时时间
})

// request拦截器
instance.interceptors.request.use(config => {
    // 在发送请求之前做些什么
    return config;
}, error => {
    // 对请求错误做些什么
    return Promise.reject(error);
})

/**
 * response拦截器
 * code:200,接口正常返回;
 */
instance.interceptors.response.use(response => {
    let { status, data, headers, config, request } = response;
    return response;
}, error => {
    const { response } = error;
    if (response) {
        let { status, data, request, config } = response;
        if(config.responseType === 'blob') {
            let reader = new FileReader();
            reader.readAsText(data, 'utf-8');
            reader.addEventListener("loadend", function () {
                let result = JSON.parse(reader.result);
                errorHandle(status, result.message, request);
            });
        }else if(config.responseType === 'arraybuffer'){
            let enc = new TextDecoder('utf-8')
            let result = JSON.parse(enc.decode(new Uint8Array(data)))
            errorHandle(status, result.message, request);
        }else {
            let message = typeof(data) === 'object' ? data.message : data;
            errorHandle(status, message, request);
        }
        return Promise.reject(response);
    } else {
        // 处理断网的情况 eg:请求超时或断网时，更新state的network状态
        Message({
            message: error,
            type: 'error',
            duration: 3 * 1000
        })
        return Promise.reject(error)
    }
});


const request = function (options) {
    options = options || {};
    if(!options.data) {
        options.data = {}
    }
    if (utils.isEmpty(options)) {
        utils.warn('调用utils.http参数为空', options)
    }

    let defaultOpts = {
        method: 'get',
        url: '',
        baseURL: config.baseUrl,
        data: {},
        params: {},
        timeout: config.timeout || 20000,
        headers: { 'content-type': 'application/x-www-form-urlencoded' },
        responseType: 'json',
        withCredentials: false,
        validateStatus: function (status) {
            return status >= 200 && status < 300;
        }
    }
    utils.assign(defaultOpts, options);

    for (let prop in defaultOpts) {
        // 设置配置属性为null，则表示删除默认的请求属性
        if (utils.isNull(defaultOpts[prop])) {
            delete defaultOpts[prop];
            continue;
        }
        switch (prop) {
            // get请求，data参数转为params参数
            case 'data':
                if(defaultOpts.method.toLowerCase() === 'get'){
                    Object.assign(defaultOpts.params, defaultOpts[prop]);
                }
                break;
            case 'url':
                if (utils.isSiteUrl(defaultOpts['url'])) {
                    delete defaultOpts['baseURL']
                }
                break;
        }
    }

    try {
        // 处理表单数据，data为js对象则stringify处理
        if (defaultOpts['headers']['content-type'] === 'application/x-www-form-urlencoded' && (utils.isPlainObject(defaultOpts['data']) || utils.isArray(defaultOpts['data']))) {
            defaultOpts['data'] = qs.stringify(defaultOpts['data'])
        }
    } catch (err) {
        console.error(err)
        return Promise.reject(err)
    }

    return instance(defaultOpts);
}

// 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法
const requestJson = function(options) {
    let apiConfig = {
        headers: { 'content-type': 'application/json;charset=UTF-8' },
    }
    utils.assign(options, apiConfig);
    return request(options);
}
// 适用 'POST' 表单文件类上传
const requestForm = function(options) {
    let apiConfig = {
        headers: { 'content-type': 'multipart/form-data' },
    }
    utils.assign(options, apiConfig);
    return request(options);
}
export { request, requestJson, requestForm };
